package com.javacrafting.mifos.web;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.springframework.validation.Errors;
import org.springframework.web.servlet.mvc.SimpleFormController;
import com.javacrafting.mifos.domain.CustomerRepository;
import com.javacrafting.mifos.domain.LoanProduct;
import com.javacrafting.mifos.domain.LoanProductFund;
import com.javacrafting.mifos.domain.LoanProductRepository;
import com.javacrafting.mifos.domain.LookupValue;
import com.javacrafting.mifos.domain.LookupValueRepository;

/**
 *
 */
public class CreateLoanAccountFormController extends SimpleFormController
{

	private final LoanAccountServiceFacade	loanAccountServiceFacade;
	private final CustomerRepository		customerRepository;
	private final LoanProductRepository		loanProductRepository;
	private final LookupValueRepository		lookupValueRepository;

	public CreateLoanAccountFormController(final LoanAccountServiceFacade loanAccountServiceFacade,
			final CustomerRepository customerService, final LoanProductRepository loanProductRepository,
			final LookupValueRepository lookupValueRepository)
	{
		this.loanAccountServiceFacade = loanAccountServiceFacade;
		this.customerRepository = customerService;
		this.loanProductRepository = loanProductRepository;
		this.lookupValueRepository = lookupValueRepository;
	}

	@Override
	protected void onBind(HttpServletRequest request, Object command) throws Exception
	{
		super.onBind(request, command);
	}

	@Override
	protected void doSubmitAction(Object command) throws Exception
	{
		LoanAccountFormCommand form = (LoanAccountFormCommand) command;
		loanAccountServiceFacade.saveLoanAccount(form);
	}

	@Override
	protected Map referenceData(HttpServletRequest request, Object command, Errors errors) throws Exception
	{

		Map<Object, Object> dataMap = new HashMap<Object, Object>();
		final Integer customerId = Integer.parseInt(request.getParameter("customerId"));
		final Short loanProductId = Short.parseShort(request.getParameter("loanProductId"));

		final String customerName = customerRepository.findById(customerId).getDisplayName();

		LoanProduct product = loanProductRepository.findLoanProductById(loanProductId);

		final String loanProductName = product.getName();
		final String loanProductDescription = product.getDescription();
		final String loanProductInterestRatePropertyKey = product.interestRateTypePropertyKey();

		List<LabelValue<Short>> sourceOfFundsList = createSourceOfFundsDropDownList(product.getLoanProductFunds());

		final Integer purposeOfLoanGroupId = Integer.valueOf(82);
		List<LabelValue<Integer>> purposeOfLoansList = createDropDownList(lookupValueRepository.findByGroupId(purposeOfLoanGroupId));
		
		final Integer collateralTypeGroupId = Integer.valueOf(43);
		List<LabelValue<Integer>> collateralTypesList = createDropDownList(lookupValueRepository.findByGroupId(collateralTypeGroupId));

		List<Integer> standardFeesList = new ArrayList<Integer>();
		standardFeesList.add(Integer.valueOf(14));
		standardFeesList.add(Integer.valueOf(28));

		dataMap.put("customerName", customerName);
		dataMap.put("loanProductName", loanProductName);
		dataMap.put("loanDescription", loanProductDescription);
		dataMap.put("loanProductInterestRatePropertyKey", loanProductInterestRatePropertyKey);
		dataMap.put("sourceOfFundsList", sourceOfFundsList);
		dataMap.put("purposeOfLoansList", purposeOfLoansList);
		dataMap.put("collateralTypesList", collateralTypesList);
		
		dataMap.put("standardFees", standardFeesList);
		return dataMap;
	}

	@Override
	protected Object formBackingObject(HttpServletRequest request) throws Exception
	{
		final Integer customerId = Integer.parseInt(request.getParameter("customerId"));
		final Short loanProductId = Short.parseShort(request.getParameter("loanProductId"));

		List<Integer> standardFeesList = new ArrayList<Integer>();
		standardFeesList.add(Integer.valueOf(14));
		standardFeesList.add(Integer.valueOf(28));

		LoanAccountFormCommand form = new LoanAccountFormCommand();
		form.setCustomerId(customerId);
		form.setLoanProductId(loanProductId);
		form.setStandardFees(standardFeesList);
		return form;
	}

	private List<LabelValue<Short>> createSourceOfFundsDropDownList(Set<LoanProductFund> loanProductFunds)
	{
		List<LabelValue<Short>> labelValueList = new ArrayList<LabelValue<Short>>();
		for (LoanProductFund loanProductFund : loanProductFunds)
		{
			labelValueList.add(new LabelValueImpl<Short>(loanProductFund.getFundId(), loanProductFund.getFundName()));
		}
		return labelValueList;
	}
	
	private List<LabelValue<Integer>> createDropDownList(List<LookupValue> lookupValues)
	{
		List<LabelValue<Integer>> labelValueList = new ArrayList<LabelValue<Integer>>();
		for (LookupValue lookupValue : lookupValues)
		{
			labelValueList.add(new LabelValueImpl<Integer>(lookupValue.getId(), lookupValue.getValue()));
		}
		return labelValueList;
	}
}
